feat(auth): 支持 --cookie 手动导入登录态 & 修复 macOS 登录链路#2
Open
1yx wants to merge 3 commits into
Open
Conversation
在 macOS 上 douban login 自动登录常因 keychain 权限失败而抓不到登录态, puppeteer 路径存在必然超时的 bug,交互式路径在多 profile 用户身上也抓不到 cookie、会触发无关浏览器授权弹窗、并存在惰性写盘导致的「假成功」。本提交 补齐手动导入兜底并修复整条登录链路。 主要改动: 1. login --cookie:支持 Netscape cookies.txt 文件路径或原始 Cookie 字符串, 解析 dbcl2(必需)+ ck(可选),跳过浏览器流程。 2. 修复 puppeteer:dbcl2 是 HttpOnly,旧实现 waitForFunction 读 document.cookie 永远不成立、必然 180s 超时;改为轮询 CDP page.cookies()。 3. ensureAuth 不再自动触发交互式登录(行为变更):upstream 在 whoami/mark 等命令无缓存时会调 loginWithBrowser,spinner 会盖住 readline 提示表现为 卡死;改为只读缓存,无缓存抛错提示显式 douban login。 4. 自动对齐 Chrome profile:resolveChromeProfile 读 Local State 的 profile.last_used 作为 chromeProfile,与 openLoginPage 实际打开的 profile 对齐(旧实现只读 Default,多 profile 用户抓不到 cookie)。 5. 只从默认浏览器提取 cookie:resolveDefaultBrowser 通过 macOS LaunchServices plist / Linux xdg-settings / Windows 注册表解析系统默认 浏览器,只试它一个(检测失败退回 chrome),消除无关浏览器的授权弹窗。 6. 登录时校验 cookie 服务端有效:Chrome cookie 惰性写盘,磁盘可能残留失效 dbcl2;新增 isValidSession(用 getCurrentUserProfile 校验),loginWithBrowser 预检查与 loginWithCookie 导入都需通过校验才存盘,杜绝「假成功」。 7. 回车后轮询提取 cookie:刚登录时新 dbcl2 未及时写盘(Chromium 批量异步 刷盘,实测约 30-50s),改为最多轮询 30 次、间隔 2s(覆盖约 60s),用值 变化判断新登录生效,spinner 反馈,命中后再校验一次。 8. 已登录时跳过登录页:loginWithBrowser 开头先 extractFromBrowsers,命中 有效 session 直接复用,不再重复打开登录页。 9. loginWithBrowser 加 spinner 反馈(交互阶段除外,避免盖住 readline)。 测试:新增 src/__tests__/auth.test.ts,覆盖 parseCookieHeader 与 parseNetscapeCookies(含 #HttpOnly_ 前缀、引号去除、缺失 dbcl2 等边界)。 文档:README 新增「登录方式」章节。
- 检测不到默认浏览器时按 chrome/edge/firefox/safari 顺序全量兜底,而非只试单个 chrome - resolveChromeProfile 仅在默认浏览器明确是 Google Chrome 时调用,避免 Brave/Arc/Vivaldi 等衍生浏览器套用错误的 Google Chrome profile - loginWithBrowser 的交互提示与 readline 改走 stderr,douban login --json 不再被污染 - parseCookieHeader 剥掉可选的 Cookie: 前缀,容忍从 F12 复制整行请求头 - 补一条 parseCookieHeader 容忍 Cookie: 前缀的测试
- Windows resolveDefaultBrowser 读 https UserChoice 而非 http(登录页是 https URL) - parseCookieHeader 的 ck 也从剥前缀后的 cleaned 解析(修上一轮 #4 的尾巴) - 轮询 cookie 时若值未变化但 isValidSession 通过则接受,应对开头预检的瞬时网络失败 - README 说明 puppeteer 需装在 CLI 同一加载上下文(全局安装),并注明 Brave/Arc/Vivaldi 等衍生浏览器暂不在自动提取覆盖范围内,建议用 --cookie 手动导入 - 补 ck 在 Cookie: 前缀场景下的测试
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(auth): 支持 --cookie 手动导入登录态 & 修复 puppeteer dbcl2 抓取
背景
在 macOS 上,
douban login自动登录需授予 keychain 权限以解密豆瓣网的 cookie,常因钥匙串/磁盘权限失败/用户不愿授权而抓不到登录态;同时 puppeteer 自动登录流程存在一个导致必然超时的 bug,且交互式登录路径在多 Chrome profile 用户身上抓不到 cookie、会触发无关浏览器的授权弹窗、存在惰性写盘导致的「假成功」。本 PR 提供手动导入 Cookie 的兜底方式,修复 puppeteer 路径,自动对齐 Chrome profile,选择系统默认浏览器,并修正douban whoami命令会误触发交互式登录的问题。改动
1. 新增
douban login --cookie(-c)手动导入登录态支持两种入参:
cookies.txt文件路径(如用「Get cookies.txt LOCALLY」扩展导出)cookie整行)跳过浏览器登录流程,从输入中解析
dbcl2(必需)与ck(可选)。2. 修复 puppeteer 自动登录必然超时的 bug
旧实现用
page.waitForFunction(() => document.cookie.includes('dbcl2='))等待登录成功,但dbcl2是 HttpOnly cookie,document.cookie读不到,必然 180s 超时。改为轮询 CDP 的page.cookies(),并在extractFromBrowsers失败时于 macOS 上给出 keychain / 手动导入提示。3. 改
ensureAuth不再自动触发交互式登录(行为变更)upstream 的
ensureAuth在无缓存时会调用loginWithBrowser(),导致whoami/mark等命令在 spinner 内触发readline等待回车,提示被 spinner(每 80ms 重写一行)盖住,表现为卡死。改为只读本地缓存,无缓存则抛错并提示显式运行douban login。4. 自动对齐 Chrome profile
openLoginPage()用系统默认浏览器打开登录页,Chrome 会在「最近使用的 profile」里打开;但extractFromBrowsers()只读Defaultprofile,两者错位就抓不到 cookie(多 profile 用户尤其常见)。新增resolveChromeProfile():读取 ChromeLocal State的profile.last_used,作为chromeProfile传给 sweet-cookie,使提取与实际登录的 profile 对齐。5. 只从默认浏览器提取 cookie,避免无关授权弹窗
sweet-cookie对browsers列表是「全试 + 合并」、不短路;旧实现传入全部 4 个浏览器,导致 Chrome 用户也会被 Edge/Safari 的 keychain/磁盘权限弹窗打扰。新增resolveDefaultBrowser():通过 macOS LaunchServices plist / Linuxxdg-settings/ Windows 注册表解析系统默认浏览器(即openLoginPage实际打开页面的那个)。由于openLoginPage只在默认浏览器打开登录页,用户只能在那里登录,cookie 也必然在那里,因此只试默认浏览器即可(检测失败退回最常见的 chrome),不再全量试所有浏览器。6. 登录时校验 cookie 服务端有效,杜绝「假成功」
Chrome cookie 是惰性写盘:浏览器里登出后,磁盘 SQLite 仍可能残留失效 dbcl2,
extractFromBrowsers读文件会拿到失效 cookie。旧实现直接存盘并报「登录成功」,用户直到跑whoami/mark会出现没登录。新增isValidSession(用getCurrentUserProfile校验 dbcl2 服务端有效):loginWithBrowser的「已登录」预检查:existing必须通过校验才存盘返回,否则继续走登录流程loginWithCookie(--cookie导入):解析成功后校验,失败抛明确错误(避免导入过期/错误 cookie 造成假成功)7. 回车后轮询提取 cookie,应对 Chrome 惰性写盘(对称问题)
惰性写盘的对称问题:刚登录时 dbcl2 先在 Chrome 内存里、未及时写盘(Chromium 批量异步刷盘,实测约 30-50s),用户按回车时
extractFromBrowsers读文件读不到,误报「未提取到 dbcl2」。改为按回车后轮询:最多 30 次、间隔 2s(覆盖约 60s flush 窗口),用 spinner 反馈(此时 readline 已关闭,spinner 安全)。若磁盘残留旧失效 dbcl2,首次读到的是旧值,因此用「值变化」判断新登录生效(新登录会换发新 token;之前未登录则任何 dbcl2 都算新);命中后再isValidSession校验一次。失败提示补充「Chrome 约每 30-50s 落盘一次,可稍后重试」。8. 已登录时跳过登录页
loginWithBrowser开头先extractFromBrowsers()检查是否已处于登录态,命中则直接返回,不再打开登录页或触发 puppeteer。豆瓣在浏览器里已是登录状态时,douban login直接复用现有 cookie。9.
loginWithBrowser增加 spinner 提示puppeteer 阶段用 spinner 给反馈(puppeteer 缺失/失败会快速返回 null);交互阶段不用 spinner 以免盖住 readline 提示。
10. 测试
新增
src/__tests__/auth.test.ts,覆盖parseCookieHeader与parseNetscapeCookies(含#HttpOnly_前缀、引号去除、缺失 dbcl2 等边界)。11. 文档
README 新增「登录方式」章节(手动 Cookie / puppeteer 自动登录,及 puppeteer 需自行安装以避免 ~300MB Chromium 下载)。
文件
使用示例
Fixes #1